﻿__author__ = "Dani Carrera"
__copyright__ = "Copyright 2012, PyXMLRPCPOS"
__credits__ = ["Dani Carrera"]
__license__ = "GPL"
__status__ = "Alpha"

from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
import win32print

#printer name
Printer = 'T88 Receipt'
#currency symbol
eur = chr(0xd5)
#return
n = chr(0xa)
#tab
tab = chr(0x09)

def Print(datos):
    win32print.WritePrinter(printer, datos)
    
def Start():
    global printer
    printer = win32print.OpenPrinter(Printer, None)
    win32print.StartDocPrinter(printer, 1, ('Ticket 22',None,'raw'))
    #inicia la impresora
    Print(chr(0x1b)+chr(0x40))
    #pone el mapa de caracteres en el de euro
    Print(chr(0x1B)+"t"+chr(19))

    #indica la anchura del papel
    #Print(chr(0x1d)+chr(0x50)+chr(180)+chr(180))

    #indica la separacion entre lineas por defecto
    #Print(chr(0x1B)+chr(33)+chr(35))

def Stop():
    win32print.EndDocPrinter(printer)
    win32print.ClosePrinter(printer)

def Just(jus="l"):
    #Justifica el texto izq centro o derecha
    if jus == "c": jus = 1
    elif jus == "r": jus = 2
    else: jus = 0
    Print(chr(0x1b)+chr(0x61)+chr(jus))

def separacionLineas(cantidad=3):
    #Agrega x lineas de separacion entre lineas
    Print(chr(0x1b)+chr(0x64)+chr(cantidad))    

def BarCode(tipo=65, codigo="123456789012", altura=80):
    #_id_|_____tipo_____|_longitud_| 
    #_65_|_upc-a________| 11 o 12  |
    #_66_|_upc-e________| 11 o 12  |
    #_67_|_ean13________| 12 o 13  |
    #_68_|_ean8_________|__(7o8)___|
    #_69_|_code39(1a255)
    #_70_|_itf(1a255num)
    #_71_|_codabar(1a255)
    #_72_|_code93 (1a255)
    #_73_|_code128(2a255)
    
    #anchura
    #CHR$(&H1D);"w";CHR$(5);

    #AlturaPrint
    altura = chr(0x1d)+chr(0x68)+chr(altura)
    #anchura = chr(0x1d)+chr(0x77)+chr(anchura)
    codigo = chr(0x1d)+chr(0x6b)+chr(65)+chr(12)+chr(50)+codigo+chr(50)+chr(12)
    Print(altura+codigo+r)

def Cut(par=1):
    #1 par. 0 total
    Print(chr(0x1d)+chr(0x56)+chr(par))

def Open(pin=0):
    #on 25 × 2 msec, off 250 × 2 msec
    #0 o 48 = pin 2
    #1 o 49 = pin 5
    Print(chr(0x1b)+chr(0x70)+chr(pin)+chr(25)+chr(250))

def Rel(r=0):
    #posicion relativa del cursor
    return chr(0x1b)+chr(0x5c)+chr(r)+chr(0)

def Abs(a=0):
    #posicion absoluta del cursor
    return chr(0x1b)+chr(0x24)+chr(a)+chr(0)

#chr(0x1D)+"W"+chr(180)+chr(0)#anchura del campo de escritura

def Style(font=0,bold=0,doh=0,dow=0,under=0):
    #example for font2 bold and underline...
    #style(bold=1,under=1,font=1)
    #
    if font == 1:font = 1
    else: font = 0
    if bold == 1:bold = 8
    else: bold = 0
    if doh == 1:doh = 16
    else: doh = 0
    if dow == 1:dow = 32
    else: dow = 0
    if under == 1:under = 128
    else: under = 0
    Print(chr(0x1B)+"!"+chr(font+bold+doh+dow+under))

#############################end##########################################

def TicketPOS():
    Start()
    Style(dow=1,doh=1,font=1)
    Just('c')
    
    Print('Hello'+n)

    Just('l')
    Style(dow=1,doh=1,font=1)

    Print(tab+'World'+n)
    
    BarCode()
    Cut()
    Stop()

    return True

def openDrawer():
    Start()
    Open()
    Stop()


# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/POS',)

    def do_OPTIONS(self):
        origin = self.headers.get('Origin')
        self.send_response(200)
        self.send_header("Access-Control-Allow-Headers", "Origin, Content-Type")
        self.send_header("Access-Control-Allow-Origin", origin)
        self.send_header("Access-Control-Allow-Methods", "POST")
        self.end_headers()
        
    def do_POST(self):
        """Handles the HTTP POST request.

        Attempts to interpret all HTTP POST requests as XML-RPC calls,
        which are forwarded to the server's _dispatch method for handling.
        """

        # Check that the path is legal
        if not self.is_rpc_path_valid():
            self.report_404()
            return
    
        try:
            # Get arguments by reading body of request.
            # We read this in chunks to avoid straining
            # socket.read(); around the 10 or 15Mb mark, some platforms
            # begin to have problems (bug #792570).
            max_chunk_size = 10*1024*1024
            size_remaining = int(self.headers["content-length"])
            L = []
            while size_remaining:
                chunk_size = min(size_remaining, max_chunk_size)
                L.append(self.rfile.read(chunk_size))
                size_remaining -= len(L[-1])
            data = ''.join(L)

            data = self.decode_request_content(data)
            if data is None:
                return #response has been sent

            # In previous versions of SimpleXMLRPCServer, _dispatch
            # could be overridden in this class, instead of in
            # SimpleXMLRPCDispatcher. To maintain backwards compatibility,
            # check to see if a subclass implements _dispatch and dispatch
            # using that method if present.
            response = self.server._marshaled_dispatch(
                    data, getattr(self, '_dispatch', None), self.path
                )
        except Exception, e: # This should only happen if the module is buggy
            # internal error, report as HTTP server error
            self.send_response(500)

            # Send information about the exception if requested
            if hasattr(self.server, '_send_traceback_header') and \
            self.server._send_traceback_header:
                self.send_header("X-exception", str(e))
                self.send_header("X-traceback", traceback.format_exc())

                self.send_header("Content-length", "0")
                self.end_headers()
        else:
            # got a valid XML RPC response
            self.send_response(200)
            self.send_header("Content-type", "text/xml")
            if self.encode_threshold is not None:
                if len(response) > self.encode_threshold:
                    q = self.accept_encodings().get("gzip", 0)
                    if q:
                        try:
                            response = xmlrpclib.gzip_encode(response)
                            self.send_header("Content-Encoding", "gzip")
                        except NotImplementedError:
                            pass
            origin = self.headers.get('Origin')
            self.send_header("Access-Control-Allow-Origin", origin)
            self.send_header("Content-length", str(len(response)))
            self.end_headers()
            self.wfile.write(response)        

            
    

#RPC server
server = SimpleXMLRPCServer(("localhost", 8000), requestHandler=RequestHandler)
server.register_introspection_functions()

#Functions registered for RPC (function, alias)
server.register_function(TicketPOS, 'ticket')
server.register_function(openDrawer, 'open')

#main loop
server.serve_forever()


